-- ************************************************************************
--带有NodeMCU的ESP8266的MQ-135模块（固件需要adc库）
--
--基于GeorgK的C语言编写的MQ135 Arduino库
--见https://github.com/GeorgK/MQ135/
--由tricoos@github.com编码
--
--许可证：GNU通用公共许可证v3.0
-- ************************************************************************

local moduleName = ...
local M = {}
_G[moduleName] = M

-- 电路板上的负载电阻
local RLOAD = 10.0

-- 大气二氧化碳浓度下的校准电阻
local RZERO = 76.63

-- 从传感器电阻计算CO2 ppm值的参数
local PARA = 116.6020682
local PARB = 2.769034857

-- 温湿度依赖模型参数
local CORA = 0.00035
local CORB = 0.02718
local CORC = 1.39538
local CORD = 0.0018

-- 用于校准的大气二氧化碳水平，原始代码为397.13
-- 从https://zh-cn.co2.earth/获取当前值
local ATMOCO2 = 406.75

-- 获取校正因子以校正温度和湿度
-- t 周围空气温度
-- h  相对湿度
-- @返回计算的校正因子
function M.getCorrectionFactor(t, h)
  return CORA * t * t - CORB * t + CORC - (h-33.0)*CORD;
end

--  获取传感器的电阻，即测量值。
-- @返回传感器电阻，单位为千欧姆
function M.getResistance()
  local val = adc.read(0);
  return ((1023./val) * 5.0 - 1.0)*RLOAD;
end

-- 获得传感器的电阻，即测量值修正为 temp/hum
-- t  环境空气温度
-- h  相对湿度
-- @return 返回校正的传感器电阻（千欧姆）
function M.getCorrectedResistance(t, h)
  return M.getResistance()/M.getCorrectionFactor(t, h);
end

-- 获得二氧化碳的ppm值 (假设空气中只有二氧化碳)
-- @返回空气中二氧化碳的ppm值
function M.getPPM()
  --return PARA * math.pow((getResistance()/RZERO), -PARB);
  return PARA * math.pow((M.getResistance()/RZERO), (PARB * - 1));
end

-- 获得二氧化碳的ppm值 (假设空气中只有二氧化碳), 修正为 temp/hum
-- t  环境空气温度
-- h  相对湿度
-- @返回空气中二氧化碳的ppm值
function M.getCorrectedPPM(t, h)
  --return PARA * math.pow((getCorrectedResistance(t, h)/RZERO), -PARB);
  return PARA * math.pow((M.getCorrectedResistance(t, h)/RZERO), (PARB * -1));
end

-- 得到校准用的传感器的电阻rzero
-- @返回校准用的传感器的电阻rzero
function M.getRZero()
  return M.getResistance() * math.pow((ATMOCO2/PARA), (1.0/PARB));
end

-- 获取用于校准的传感器校正电阻RZero
-- t  环境空气温度
-- h  相对湿度
-- @返回用于校准的传感器校正电阻RZero（千欧姆）
function M.getCorrectedRZero(t, h)
  return M.getCorrectedResistance(t, h) * math.pow((ATMOCO2/PARA), (1.0/PARB));
end 

-- 覆盖默认值
function M.setRZero(resistance)
    RZERO = resistance
end

-- 电路板电阻（欧姆）
function M.setRLoad(resistance)
    RLOAD = resistance
end

return M
